/**
 * Copyright (c) 2016-2019 九点科技 All rights reserved.
 *
 * http://www.9dyun.cn
 *
 * 版权所有，侵权必究！
 */
package com.dian.modules.pos.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.dian.common.utils.*;

import com.dian.common.validator.ValidatorUtils;
import com.dian.common.validator.group.AddGroup;
import com.dian.common.validator.group.UpdateGroup;
import com.dian.modules.enums.pos.PurchaseHead_PurchaseStateEnum;
import com.dian.modules.inv.entity.InHeadEntity;
import com.dian.modules.inv.entity.InLineEntity;
import com.dian.modules.pos.entity.PurchaseLineEntity;
import com.dian.modules.pos.service.PurchaseLineService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.dian.common.exception.RRException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import org.apache.commons.collections.CollectionUtils;
import com.dian.common.server.CommonService;
import com.dian.modules.pos.dao.PurchaseHeadDao;
import com.dian.modules.pos.entity.PurchaseHeadEntity;
import com.dian.modules.pos.service.PurchaseHeadService;
import com.dian.modules.pos.vo.PurchaseHeadExportVO;
import com.dian.modules.pos.vo.SalePurchaseLineExportVO;
/**
 * 采购订单服务实现类
 *
 * @author xiaolai
 * @email xiaolai@9dyun.cn
 * @date 2019-06-24 09:40:47
 */
@Service("purchaseHeadService")

public class PurchaseHeadServiceImpl extends ServiceImpl<PurchaseHeadDao, PurchaseHeadEntity> implements PurchaseHeadService {

    protected Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    public CommonService commonService;

    @Autowired
    public PurchaseLineService purchaseLineService;

    /**
     * 采购订单分页
     * @param params
     * @return
     */
    @Override
    public PageUtils queryPage(Map<String, Object> params) {

        IPage<PurchaseHeadEntity> page = this.page(new Query<PurchaseHeadEntity>().getPage(params),getQueryWrapper(params) );
        return new PageUtils(page);
    }

    /**
    *  采购订单新增
    * @param purchaseHeadEntity
    * @return
    */
    @Override
    @Transactional(rollbackFor = Throwable.class)
    public boolean saveInfo(PurchaseHeadEntity purchaseHeadEntity) {

        //设置编码，等基础默然初始化数据设置
        purchaseHeadEntity.setPurchaseNo(commonService.getCode(PurchaseHeadEntity.class));
        //purchaseHeadEntity.setOrderDate(new Date());


        //数据完整性校验
        this.paramsCheck(purchaseHeadEntity,AddGroup.class);

        //汇总明细基础数量
        this.sumBaseNum(purchaseHeadEntity);

        //保存主表
        this.save(purchaseHeadEntity);

        //保存从表
        if (CollectionUtils.isNotEmpty(purchaseHeadEntity.getPurchaseLineEntityList())) {
            List<PurchaseLineEntity> detailList = purchaseHeadEntity.getPurchaseLineEntityList();
            for (PurchaseLineEntity detail : detailList) {
                detail.setPurchaseId(purchaseHeadEntity.getId());
            }
            purchaseLineService.saveBatch(purchaseHeadEntity.getPurchaseLineEntityList());
        }
        return true;
    }

    /**
     *采购订单更新
     * @param purchaseHeadEntity
     * @return
     */
    @Override
    public boolean updateInfo(PurchaseHeadEntity purchaseHeadEntity) {

        //修改状态校验
        this.updateCheck(purchaseHeadEntity.getId());

        //主表数据完整性校验
        this.paramsCheck(purchaseHeadEntity, UpdateGroup.class);

        //汇总明细基础数量
        this.sumBaseNum(purchaseHeadEntity);

        //更新主表
        this.updateById(purchaseHeadEntity);

        //更新从表
        purchaseLineService.updateInfo(purchaseHeadEntity);


        return true;
    }

    /**
     *采购订单删除
     * @param id
     * @return
     */
    @Override
    public boolean deleteInfo(Long id) {

        //删除状态校验
        this.deleteCheck(id);

        //更新从表
        purchaseLineService.deleteInfo(id);

        //更新主表
        this.remove(new QueryWrapper<PurchaseHeadEntity>().eq("id",id));

        return true;
    }

    /**
     * 采购订单详情
     * @param id
     * @return
     */
    @Override
    public PurchaseHeadEntity getInfo(Long id) {
        PurchaseHeadEntity purchaseHeadEntity =getById(id);
        List<PurchaseLineEntity> lineList=purchaseLineService.queryLineList(id);
        purchaseHeadEntity.setPurchaseLineEntityList(lineList);
        return purchaseHeadEntity;
    }

    /**
     * 采购订单审核
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Throwable.class)
    public boolean checkInfo(Long id) {
        PurchaseHeadEntity purchaseHeadEntity =this.getById(id);
        checkCheck(purchaseHeadEntity);
        //设置采购单状态
        purchaseHeadEntity.setPurchaseState(PurchaseHead_PurchaseStateEnum.AUDITED.getValue());
        purchaseHeadEntity.setCheckDate(new Date());
        purchaseHeadEntity.setCheckUserId(commonService.getUserId());
        purchaseHeadEntity.setCheckUserName(commonService.getUserName());
        //purchaseHeadEntity.setOrderState(OrderHead_OrderStateEnum.AUDITED.getValue());
        //purchaseHeadEntity.setOrderDate(new Date());
        ///purchaseHeadEntity.setCheckUserId(commonService.getUserId());
        //purchaseHeadEntity.setCheckUserName(commonService.getUserName());
        return this.updateById(purchaseHeadEntity);
    }

    /**
     *采购订单当前页or全部导出
     * @param params
     * @return
     */
    @Override
    public List<PurchaseHeadExportVO> exportList(Map<String, Object> params) {
        List<PurchaseHeadEntity> list;
        if(!StrUtil.isBlankIfStr(params.get("exprotType"))){
            list= this.page(new Query<PurchaseHeadEntity>().getPage(params),getQueryWrapper(params)).getRecords();
        }else{
            list= this.list(getQueryWrapper(params));
        }
        List<PurchaseHeadExportVO> resultList = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(list)) {
            resultList = BeanConverter.convertList(list, PurchaseHeadExportVO.class);
            // 封装明细
            if(CollectionUtils.isNotEmpty(resultList)){
                for(PurchaseHeadExportVO purchaseHeadEntity : resultList){
                    List<PurchaseLineEntity>  salePurchaseLineEntityList = purchaseLineService.queryLineList(purchaseHeadEntity.getId());
                    purchaseHeadEntity.setSalePurchaseLineExportVOList(BeanConverter.convertList( salePurchaseLineEntityList, SalePurchaseLineExportVO.class));
                }
            }
        }
        return resultList;
    }


    /**
     * 更新采购订单已入库数量
     * @param inHeadEntity
     * @return
     */
    @Transactional(rollbackFor = Throwable.class)
    public boolean updatePosNum(InHeadEntity inHeadEntity){
        List<InLineEntity> inList=inHeadEntity.getInLineEntityList();
        if(CollectionUtils.isEmpty(inList)){
            return false;
        }

        PurchaseHeadEntity purchaseHeadEntity=this.getInfo(inHeadEntity.getSourceId());
        List<PurchaseLineEntity> posList=purchaseHeadEntity.getPurchaseLineEntityList();
        BigDecimal sumInBaseNum = new BigDecimal("0");
        for (int i=0;i<posList.size();i++){
            PurchaseLineEntity k=posList.get(i);
            for (int j=0;j<inList.size();j++){
                InLineEntity v=inList.get(j);
                if(v.getGoodsId().equals(k.getGoodsId())){
                    if(k.getBaseNum().compareTo(v.getBaseNum())<0){
                        throw new RRException(String.format("%s 入库基础数量大于采购基础数量", v.getGoodsName()));
                    }
                   /* if(k.getQtyNum().compareTo(v.getQtyNum())<0){
                        throw new RRException(String.format("%s 入库库存数量大于采购库存数量",  v.getGoodsName()));
                    }
                    if(k.getAuxNum().compareTo(v.getAuxNum())<0){
                        throw new RRException(String.format("%s 入库辅助数量大于采购辅助数量",  v.getGoodsName()));
                    }*/
                    k.setInBaseNum(k.getInBaseNum().add(v.getBaseNum()));
                    k.setInAuxNum(k.getInAuxNum().add(v.getAuxNum()));
                    k.setInQtyNum(k.getInAuxNum().add(v.getQtyNum()));
                    sumInBaseNum= sumInBaseNum.add(v.getBaseNum());
                }
            }
        }

        purchaseHeadEntity.setInSumNum(purchaseHeadEntity.getInSumNum().add(sumInBaseNum));
        //更新主表
        this.updateById(purchaseHeadEntity);
        //更新从表
        purchaseLineService.updateInfo(purchaseHeadEntity);
        return true;
    }


    /***********************************************************************************************/
    /****************************************** 私有方法 ********************************************/
    /***********************************************************************************************/

    /**
     * 修改状态校验
     *
     * @param
     */
    private void updateCheck(Long id) {
        PurchaseHeadEntity purchaseHeadEntity =this.getById(id);
        if(purchaseHeadEntity.getPurchaseState().equals(PurchaseHead_PurchaseStateEnum.AUDITED.getValue())){
            throw new RRException(String.format("[%s] 当前订单已审核状态,禁止修改",purchaseHeadEntity.getPurchaseNo()));
        }
        //if(purchaseHeadEntity.getOrderState().equals(PurchaseHead_OrderStateEnum.AUDITED.getValue())){
        //     throw new RRException(String.format("[%s] 当前订单非未审核状态,禁止修改",purchaseHeadEntity.getProbNo()));
        //}
    }
    /**
     * 审核状态校验
     *
     * @param
     */
    private void checkCheck(PurchaseHeadEntity purchaseHeadEntity) {
        if(purchaseHeadEntity.getPurchaseState().equals(PurchaseHead_PurchaseStateEnum.AUDITED.getValue())){
            throw new RRException(String.format("[%s] 当前单据已审核 ",purchaseHeadEntity.getPurchaseNo()));
        }

        //if(purchaseHeadEntity.getOrderState().equals(OrderHead_OrderStateEnum.AUDITED.getValue())){
        //    throw new RRException(String.format("[%s] 当前订单非未审核状态,禁止审核",probHeadEntity.getProbNo()));
        //}
    }

    /**
     * 删除状态校验
     *
     * @param
     */
    private void deleteCheck(Long id) {
        PurchaseHeadEntity purchaseHeadEntity =this.getById(id);
        if(purchaseHeadEntity.getPurchaseState().equals(PurchaseHead_PurchaseStateEnum.AUDITED.getValue())){
            throw new RRException(String.format("[%s] 当前单据已审核,禁止审核",purchaseHeadEntity.getPurchaseNo()));
        }
        //if(!purchaseHeadEntity.getOrderState().equals(PurchaseHead_OrderStateEnum.WAITCHECK.getValue())){
        //    throw new RRException(String.format("[%s] 当前订单非未审核状态,禁止删除",PurchaseHeadEntity.getProbNo()));
        //}
    }
    /**
     * 统计
     *
     * @param record
     */
    private void sumBaseNum(PurchaseHeadEntity record) {
        BigDecimal sumBaseNum=new BigDecimal("0");
        for (PurchaseLineEntity salePurchaseLineEntity : record.getPurchaseLineEntityList()) {
            sumBaseNum=sumBaseNum.add(salePurchaseLineEntity.getBaseNum());
        }
        record.setSumNum(sumBaseNum);
    }
    /**
     * 新增和修改参数校验
     *
     * @param record
     */
    private void paramsCheck(PurchaseHeadEntity record, Class<?> cls) {

        //设置明细的主表ID
        ListUtils.setPropertyValue(record.getPurchaseLineEntityList(),"purchaseId",record.getId());

        logger.debug("明细{}", JSON.toJSONString(record.getPurchaseLineEntityList()));
        ValidatorUtils.validateEntity(record, cls);

        if (CollectionUtils.isEmpty(record.getPurchaseLineEntityList())) {
            throw new RRException("采购订单明细数据不能为空");
        }
        for (PurchaseLineEntity salePurchaseLineEntity : record.getPurchaseLineEntityList()) {
            int index = record.getPurchaseLineEntityList().indexOf(salePurchaseLineEntity) + 1;
            try {
                ValidatorUtils.validateEntity(salePurchaseLineEntity, cls);
            }catch (RRException e){
                throw new RRException(String.format("第%s行 预订单明细校验失败<br/>"+e.getMsg(), index));
            }
        }
    }

    /**
     * 获取查询条件
     *
     * @param
     */
    private QueryWrapper<PurchaseHeadEntity> getQueryWrapper(Map<String, Object> params) {
        QueryWrapper<PurchaseHeadEntity> queryWrapper=new QueryWrapper<>();
        if(!StrUtil.isBlankIfStr(params.get("purchaseDate"))){
            String purchaseDate=String.valueOf(params.get("purchaseDate"));
            String[] purchaseDateRange=purchaseDate.split("至");
            if(purchaseDateRange.length==2){
                queryWrapper.gt("purchase_date",DateUtils.getBeginTimeOfDate(purchaseDateRange[0]));
                queryWrapper.lt("purchase_date",DateUtils.getBeginTimeOfDate(purchaseDateRange[1]));
            }else{
                queryWrapper.gt("purchase_date",DateUtils.getBeginTimeOfDate(purchaseDate));
            }
        }
        if(!StrUtil.isBlankIfStr(params.get("purchaseState"))){
            queryWrapper.eq("purchase_state",params.get("purchaseState"));
        }

        if(!StrUtil.isBlankIfStr(params.get("supplierName"))){
            queryWrapper.like("supplier_name",params.get("supplierName"));
        }
        if(!StrUtil.isEmptyIfStr(params.get("propKey"))){
            queryWrapper.and(wrapper -> wrapper
                    .like("purchase_no", params.get("propKey"))
                    .or()
                    .like("supplier_name", params.get("propKey")
                     )
            );
        }
        queryWrapper.orderByAsc("id");
        return queryWrapper;
    }
}
